home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume14 / flex / part03 < prev    next >
Encoding:
Internet Message Format  |  1988-05-02  |  48.8 KB

  1. Subject:  v14i081:  Flex, a lex replacement, Part03/05
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Vern Paxson <vern@lbl-csam.arpa>
  7. Posting-number: Volume 14, Issue 81
  8. Archive-name: flex/part03
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 3 (of 5)."
  17. # Contents:  flex.1 flexdef.h nfa.c
  18. # Wrapped by rsalz@fig.bbn.com on Tue May  3 17:31:30 1988
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'flex.1' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'flex.1'\"
  22. else
  23. echo shar: Extracting \"'flex.1'\" \(15558 characters\)
  24. sed "s/^X//" >'flex.1' <<'END_OF_FILE'
  25. X.TH FLEX 1 "13 May 1987"
  26. X.SH NAME
  27. flex - fast lexical analyzer generator
  28. X.SH SYNOPSIS
  29. X.B flex
  30. X[
  31. X.B -dfirstvFILT -c[efmF] -Sskeleton_file
  32. X] [ 
  33. X.I filename
  34. X]
  35. X.SH DESCRIPTION
  36. X.I flex
  37. is a rewrite of
  38. X.I lex
  39. intended to right some of that tool's deficiencies: in particular,
  40. X.I flex
  41. generates lexical analyzers much faster, and the analyzers use
  42. smaller tables and run faster.
  43. X.SH OPTIONS
  44. In addition to lex's
  45. X.B -t
  46. flag, flex has the following options:
  47. X.TP
  48. X.B -d
  49. makes the generated scanner run in
  50. X.I debug
  51. mode.  Whenever a pattern is recognized the scanner will
  52. write to
  53. X.I stderr
  54. a line of the form:
  55. X.nf
  56. X
  57. X    --accepting rule #n
  58. X
  59. X.fi
  60. Rules are numbered sequentially with the first one being 1.
  61. X.TP
  62. X.B -f
  63. has the same effect as lex's -f flag (do not compress the scanner
  64. tables); the mnemonic changes from
  65. X.I fast compilation
  66. to (take your pick)
  67. X.I full table
  68. or
  69. X.I fast scanner.
  70. The actual compilation takes
  71. X.I longer,
  72. since flex is I/O bound writing out the big table.
  73. X.IP
  74. This option is equivalent to
  75. X.B -cf
  76. X(see below).
  77. X.TP
  78. X.B -i
  79. instructs flex to generate a
  80. X.I case-insensitive
  81. scanner.  The case of letters given in the flex input patterns will
  82. be ignored, and the rules will be matched regardless of case.  The
  83. matched text given in
  84. X.I yytext
  85. will have the preserved case (i.e., it will not be folded).
  86. X.TP
  87. X.B -r
  88. specifies that the scanner uses the
  89. X.B REJECT
  90. action.
  91. X.TP
  92. X.B -s
  93. causes the
  94. X.I default rule
  95. X(that unmatched scanner input is echoed to
  96. X.I stdout)
  97. to be suppressed.  If the scanner encounters input that does not
  98. match any of its rules, it aborts with an error.  This option is
  99. useful for finding holes in a scanner's rule set.
  100. X.TP
  101. X.B -v
  102. has the same meaning as for lex (print to
  103. X.I stderr
  104. a summary of statistics of the generated scanner).  Many more statistics
  105. are printed, though, and the summary spans several lines.  Most
  106. of the statistics are meaningless to the casual flex user.
  107. X.TP
  108. X.B -F
  109. specifies that the
  110. X.ul
  111. fast
  112. scanner table representation should be used.  This representation is
  113. about as fast as the full table representation
  114. X.ul
  115. X(-f),
  116. and for some sets of patterns will be considerably smaller (and for
  117. others, larger).  In general, if the pattern set contains both "keywords"
  118. and a catch-all, "identifier" rule, such as in the set:
  119. X.nf
  120. X
  121. X    "case"    return ( TOK_CASE );
  122. X    "switch"  return ( TOK_SWITCH );
  123. X    ...
  124. X    "default" return ( TOK_DEFAULT );
  125. X    [a-z]+    return ( TOK_ID );
  126. X
  127. X.fi
  128. then you're better off using the full table representation.  If only
  129. the "identifier" rule is present and you then use a hash table or some such
  130. to detect the keywords, you're better off using
  131. X.ul
  132. X-F.
  133. X.IP
  134. This option is equivalent to
  135. X.B -cF
  136. X(see below).
  137. X.TP
  138. X.B -I
  139. instructs flex to generate an
  140. X.I interactive
  141. scanner.  Normally, scanners generated by flex always look ahead one character
  142. before deciding that a rule has been matched.  At the possible cost of some
  143. scanning overhead (it's not clear that more overhead is involved), flex will
  144. generate a scanner which only looks ahead when needed.  Such scanners are
  145. called
  146. X.I interactive
  147. because if you want to write a scanner for an interactive system such
  148. as a command shell, you will probably want the user's input to be terminated
  149. with a newline, and without
  150. X.B -I
  151. the user will have to type a character in addition to the newline in order
  152. to have the newline recognized.  This leads to dreadful interactive performance.
  153. X.IP
  154. If all this seems to confusing, here's the general rule: if a human will
  155. be typing in input to your scanner, use
  156. X.B -I,
  157. otherwise don't; if you don't care about how fast your scanners run and
  158. don't want to make any assumptions about the input to your scanner,
  159. always use
  160. X.B -I.
  161. X.IP
  162. Note,
  163. X.B -I
  164. cannot be used in conjunction with
  165. X.I full
  166. or
  167. X.I fast tables,
  168. i.e., the
  169. X.B -f, -F, -cf,
  170. or
  171. X.B -cF
  172. flags.
  173. X.TP
  174. X.B -L
  175. instructs flex to not generate
  176. X.B #line
  177. directives (see below).
  178. X.TP
  179. X.B -T
  180. makes flex run in
  181. X.I trace
  182. mode.  It will generate a lot of messages to standard out concerning
  183. the form of the input and the resultant non-deterministic and deterministic
  184. finite automatons.  This option is mostly for use in maintaining flex.
  185. X.TP 
  186. X.B -c[efmF]
  187. controls the degree of table compression.
  188. X.B -ce
  189. directs flex to construct
  190. X.I equivalence classes,
  191. i.e., sets of characters
  192. which have identical lexical properties (for example, if the only
  193. appearance of digits in the flex input is in the character class
  194. X"[0-9]" then the digits '0', '1', ..., '9' will all be put
  195. in the same equivalence class).
  196. X.B -cf
  197. specifies that the
  198. X.I full
  199. scanner tables should be generated - flex should not compress the
  200. tables by taking advantages of similar transition functions for
  201. different states.
  202. X.B -cF
  203. specifies that the alternate fast scanner representation (described
  204. above under the
  205. X.B -F
  206. flag)
  207. should be used.
  208. X.B -cm
  209. directs flex to construct
  210. X.I meta-equivalence classes,
  211. which are sets of equivalence classes (or characters, if equivalence
  212. classes are not being used) that are commonly used together.
  213. A lone
  214. X.B -c
  215. specifies that the scanner tables should be compressed but neither
  216. equivalence classes nor meta-equivalence classes should be used.
  217. X.IP
  218. The options
  219. X.B -cf
  220. or
  221. X.B -cF
  222. and
  223. X.B -cm
  224. do not make sense together - there is no opportunity for meta-equivalence
  225. classes if the table is not being compressed.  Otherwise the options
  226. may be freely mixed.
  227. X.IP
  228. The default setting is
  229. X.B -cem
  230. which specifies that flex should generate equivalence classes
  231. and meta-equivalence classes.  This setting provides the highest
  232. degree of table compression.  You can trade off
  233. faster-executing scanners at the cost of larger tables with
  234. the following generally being true:
  235. X.nf
  236. X
  237. X    slowest            smallest
  238. X               -cem
  239. X               -ce
  240. X               -cm
  241. X               -c
  242. X               -c{f,F}e
  243. X               -c{f,F}
  244. X    fastest            largest
  245. X
  246. X.fi
  247. X.TP
  248. X.B -Sskeleton_file
  249. overrides the default skeleton file from which flex constructs
  250. its scanners.  You'll never need this option unless you are doing
  251. flex maintenance or development.
  252. X.SH INCOMPATIBILITIES WITH LEX
  253. X.I flex
  254. is fully compatible with
  255. X.I lex
  256. with the following exceptions:
  257. X.IP -
  258. There is no run-time library to link with.  You needn't
  259. specify
  260. X.I -ll
  261. when linking, and you must supply a main program.  (Hacker's note: since
  262. the lex library contains a main() which simply calls yylex(), you actually
  263. X.I can
  264. be lazy and not supply your own main program and link with
  265. X.I -ll.)
  266. X.IP -
  267. lex's
  268. X.B %r
  269. X(Ratfor scanners) and
  270. X.B %t
  271. X(translation table) options
  272. are not supported.
  273. X.IP -
  274. The do-nothing
  275. X.ul
  276. X-n
  277. flag is not supported.
  278. X.IP -
  279. When definitions are expanded, flex encloses them in parentheses.
  280. With lex, the following
  281. X.nf
  282. X
  283. X    NAME    [A-Z][A-Z0-9]*
  284. X    %%
  285. X    foo{NAME}?      printf( "Found it\\n" );
  286. X    %%
  287. X
  288. X.fi
  289. will not match the string "foo" because when the macro
  290. is expanded the rule is equivalent to "foo[A-Z][A-Z0-9]*?"
  291. and the precedence is such that the '?' is associated with
  292. X"[A-Z0-9]*".  With flex, the rule will be expanded to
  293. X"foo([A-z][A-Z0-9]*)?" and so the string "foo" will match.
  294. X.IP -
  295. X.B yymore()
  296. is not supported.
  297. X.IP -
  298. The undocumented lex-scanner internal variable
  299. X.B yylineno
  300. is not supported.
  301. X.IP -
  302. If your input uses
  303. X.B REJECT,
  304. you must run flex with the
  305. X.B -r
  306. flag.  If you leave out the flag, the scanner will abort at run-time
  307. with a message that the scanner was compiled without the flag being
  308. specified.
  309. X.IP -
  310. The
  311. X.B input()
  312. routine is not redefinable, though may be called to read characters
  313. following whatever has been matched by a rule.  If
  314. X.B input()
  315. encounters and end-of-file the normal
  316. X.B yywrap()
  317. processing is done.  A ``real'' end-of-file is returned as
  318. X.I EOF.
  319. X.IP
  320. Input can be controlled by redefining the
  321. X.B YY_INPUT
  322. macro.
  323. YY_INPUT's calling sequence is "YY_INPUT(buf,result,max_size)".  Its
  324. action is to place up to max_size characters in the character buffer "buf"
  325. and return in the integer variable "result" either the
  326. number of characters read or the constant YY_NULL (0 on Unix systems)
  327. systems) to indicate EOF.  The default YY_INPUT reads from the
  328. file-pointer "yyin" (which is by default
  329. X.I stdin),
  330. so if you
  331. just want to change the input file, you needn't redefine
  332. YY_INPUT - just point yyin at the input file.
  333. X.IP
  334. A sample redefinition of YY_INPUT (in the first section of the input
  335. file):
  336. X.nf
  337. X
  338. X    %{
  339. X    #undef YY_INPUT
  340. X    #define YY_INPUT(buf,result,max_size) \\
  341. X        result = (buf[0] = getchar()) == EOF ? YY_NULL : 1;
  342. X    %}
  343. X
  344. X.fi
  345. You also can add in things like counting keeping track of the
  346. input line number this way; but don't expect your scanner to
  347. go very fast.
  348. X.IP -
  349. X.B output()
  350. is not supported.
  351. Output from the ECHO macro is done to the file-pointer
  352. X"yyout" (default
  353. X.I stdout).
  354. X.IP -
  355. Trailing context is restricted to patterns which have either
  356. a fixed-sized leading part or a fixed-sized trailing part.
  357. XFor example, "a*/b" and "a/b*" are okay, but not "a*/b*".
  358. This restriction is due to a bug in the trailing context
  359. algorithm given in
  360. X.I Principles of Compiler Design
  361. X(and
  362. X.I Compilers - Principles, Techniques, and Tools)
  363. which can result in mismatches.  Try the following lex program
  364. X.nf
  365. X
  366. X    %%
  367. X    x+/xy           printf( "I found \\"%s\\"\\n", yytext );
  368. X
  369. X.fi
  370. on the input "xxy".  (If anyone knows of a fast algorithm for
  371. finding the beginning of trailing context for an arbitrary
  372. pair of regular expressions, please let me know!)
  373. If you must have arbitrary trailing context, you can use
  374. X.B yyless()
  375. to effect it.
  376. X.IP -
  377. flex reads only one input file, while lex's input is made
  378. up of the concatenation of its input files.
  379. X.SH ENHANCEMENTS
  380. X.IP -
  381. X.I Exclusive start-conditions
  382. can be declared by using
  383. X.B %x
  384. instead of
  385. X.B %s.
  386. These start-conditions have the property that when they are active,
  387. X.I no other rules are active.
  388. Thus a set of rules governed by the same exclusive start condition
  389. describe a scanner which is independent of any of the other rules in
  390. the flex input.  This feature makes it easy to specify "mini-scanners"
  391. which scan portions of the input that are syntactically different
  392. from the rest (e.g., comments).
  393. X.IP -
  394. flex dynamically resizes its internal tables, so directives like "%a 3000"
  395. are not needed when specifying large scanners.
  396. X.IP -
  397. The scanning routine generated by flex is declared using the macro
  398. X.B YY_DECL.
  399. By redefining this macro you can change the routine's name and
  400. its calling sequence.  For example, you could use:
  401. X.nf
  402. X
  403. X    #undef YY_DECL
  404. X    #define YY_DECL float lexscan( a, b ) float a, b;
  405. X
  406. X.fi
  407. to give it the name
  408. X.I lexscan,
  409. returning a float, and taking two floats as arguments.
  410. X.IP -
  411. flex generates
  412. X.B #line
  413. directives mapping lines in the output to
  414. their origin in the input file.
  415. X.IP -
  416. You can put multiple actions on the same line, separated with
  417. semi-colons.  With lex, the following
  418. X.nf
  419. X
  420. X    foo    handle_foo(); return 1;
  421. X
  422. X.fi
  423. is truncated to
  424. X.nf
  425. X
  426. X    foo    handle_foo();
  427. X
  428. X.fi
  429. flex does not truncate the action.  Actions that are not enclosed in
  430. braces are terminated at the end of the line.
  431. X.IP -
  432. Actions can be begun with
  433. X.B %{
  434. and terminated with
  435. X.B %}.
  436. In this case, flex does not count braces to figure out where the
  437. action ends - actions are terminated by the closing
  438. X.B %}.
  439. This feature is useful when the enclosed action has extraneous
  440. braces in it (usually in comments or inside inactive #ifdef's)
  441. that throw off the brace-count.
  442. X.IP -
  443. All of the scanner actions (e.g.,
  444. X.B ECHO, yywrap ...)
  445. except the
  446. X.B unput()
  447. and
  448. X.B input()
  449. routines,
  450. are written as macros, so they can be redefined if necessary
  451. without requiring a separate library to link to.
  452. X.SH FILES
  453. X.TP
  454. X.I flex.skel
  455. skeleton scanner
  456. X.TP
  457. X.I flex.fastskel
  458. skeleton scanner for -f and -F
  459. X.TP
  460. X.I flexskelcom.h
  461. common definitions for skeleton files
  462. X.TP
  463. X.I flexskeldef.h
  464. definitions for compressed skeleton file
  465. X.TP
  466. X.I fastskeldef.h
  467. definitions for -f, -F skeleton file
  468. X.SH "SEE ALSO"
  469. X.LP
  470. lex(1)
  471. X.LP
  472. M. E. Lesk and E. Schmidt,
  473. X.I LEX - Lexical Analyzer Generator
  474. X.SH AUTHOR
  475. Vern Paxson, with the help of many ideas and much inspiration from
  476. Van Jacobson.  Original version by Jef Poskanzer.  Fast table
  477. representation is a partial implementation of a design done by Van
  478. Jacobson.  The implementation was done by Kevin Gong and Vern Paxson.
  479. X.LP
  480. Thanks to the many flex beta-testers, especially Casey Leedom,
  481. Nick Christopher, Chris Faylor, Eric Goldman, Craig Leres, Mohamed el Lozy,
  482. Esmond Pitt, Jef Poskanzer, and Dave Tallman.  Thanks to John Gilmore,
  483. Bob Mulcahy,
  484. Rich Salz, and Richard Stallman for help with various distribution headaches.
  485. X.LP
  486. Send comments to:
  487. X.nf
  488. X
  489. X     Vern Paxson
  490. X     Real Time Systems
  491. X     Bldg. 46A
  492. X     Lawrence Berkeley Laboratory
  493. X     1 Cyclotron Rd.
  494. X     Berkeley, CA 94720
  495. X
  496. X     (415) 486-6411
  497. X
  498. X     vern@lbl-{csam,rtsg}.arpa
  499. X     ucbvax!lbl-csam.arpa!vern
  500. X
  501. X.fi
  502. X.SH DIAGNOSTICS
  503. X.LP
  504. X.I flex scanner jammed -
  505. a scanner compiled with
  506. X.B -s
  507. has encountered an input string which wasn't matched by
  508. any of its rules.
  509. X.LP
  510. X.I flex input buffer overflowed -
  511. a scanner rule matched a string long enough to overflow the
  512. scanner's internal input buffer (as large as
  513. X.B BUFSIZ
  514. in "/usr/include/stdio.h").  You can edit
  515. X.I flexskelcom.h
  516. and increase
  517. X.B YY_BUF_SIZE
  518. and
  519. X.B YY_MAX_LINE
  520. to increase this limit.
  521. X.LP
  522. X.I REJECT used and scanner was
  523. X.I not generated using -r -
  524. just like it sounds.  Your scanner uses
  525. X.B REJECT.
  526. You must run flex on the scanner description using the
  527. X.B -r
  528. flag.
  529. X.LP
  530. X.I old-style lex command ignored -
  531. the flex input contains a lex command (e.g., "%n 1000") which
  532. is being ignored.
  533. X.SH BUGS
  534. X.LP
  535. Use of unput() or input() trashes the current yytext and yyleng.
  536. X.LP
  537. Use of unput() to push back more text than was matched can
  538. result in the pushed-back text matching a beginning-of-line ('^')
  539. rule even though it didn't come at the beginning of the line.
  540. X.LP
  541. Nulls are not allowed in flex inputs or in the inputs to
  542. scanners generated by flex.  Their presence generates fatal
  543. errors.
  544. X.LP
  545. Do not mix trailing context with the '|' operator used to
  546. specify that multiple rules use the same action.  That is,
  547. avoid constructs like:
  548. X.nf
  549. X
  550. X        foo/bar      |
  551. X        bletch       |
  552. X        bugprone     { ... }
  553. X
  554. X.fi
  555. They can result in subtle mismatches.  This is actually not
  556. a problem if there is only one rule
  557. using trailing context and it is the first in the list (so the
  558. above example will actually work okay).  The
  559. problem is due to fall-through in the action switch statement,
  560. causing non-trailing-context rules to execute the
  561. trailing-context code of their fellow rules.  This should
  562. be fixed, as it's a nasty bug and not obvious.  The proper fix is
  563. for flex to spit out a FLEX_TRAILING_CONTEXT_USED #define and then
  564. have the backup logic in a separate table which is consulted for
  565. each rule-match, rather than as part of the rule action.  The
  566. place to do the tweaking is in add_accept() - any kind soul want
  567. to be a hero?
  568. X.LP
  569. The pattern:
  570. X.nf
  571. X
  572. X    x{3}
  573. X
  574. X.fi
  575. is considered to be variable-length for the purposes of trailing
  576. context, even though it has a clear fixed length.
  577. X.LP
  578. Due to both buffering of input and read-ahead, you cannot intermix
  579. calls to, for example,
  580. X.B getchar()
  581. with flex rules and expect it to work.  Call
  582. X.B input()
  583. instead.
  584. X.LP
  585. The total table entries listed by the
  586. X.B -v
  587. flag excludes the number of table entries needed to determine
  588. what rule has been matched.  The number of entries is equal
  589. to the number of DFA states if the scanner was not compiled
  590. with
  591. X.B -r,
  592. and greater than the number of states if it was.
  593. X.LP
  594. The scanner run-time speeds have not been optimized as much
  595. as they deserve.  Van Jacobson's work shows that the can go quite
  596. a bit faster still.
  597. END_OF_FILE
  598. if test 15558 -ne `wc -c <'flex.1'`; then
  599.     echo shar: \"'flex.1'\" unpacked with wrong size!
  600. fi
  601. # end of 'flex.1'
  602. fi
  603. if test -f 'flexdef.h' -a "${1}" != "-c" ; then 
  604.   echo shar: Will not clobber existing file \"'flexdef.h'\"
  605. else
  606. echo shar: Extracting \"'flexdef.h'\" \(17327 characters\)
  607. sed "s/^X//" >'flexdef.h' <<'END_OF_FILE'
  608. X/*
  609. X *  Definitions for flex.
  610. X *
  611. X * modification history
  612. X * --------------------
  613. X * 02b kg, vp   30sep87  .added definitions for fast scanner; misc. cleanup
  614. X * 02a vp       27jun86  .translated into C/FTL
  615. X */
  616. X
  617. X/*
  618. X * Copyright (c) 1987, the University of California
  619. X * 
  620. X * The United States Government has rights in this work pursuant to
  621. X * contract no. DE-AC03-76SF00098 between the United States Department of
  622. X * Energy and the University of California.
  623. X * 
  624. X * This program may be redistributed.  Enhancements and derivative works
  625. X * may be created provided the new works, if made available to the general
  626. X * public, are made available for use by anyone.
  627. X */
  628. X
  629. X#include <stdio.h>
  630. X
  631. X#ifdef SV
  632. X#include <string.h>
  633. X#define bzero(s, n) memset((char *)(s), '\000', (unsigned)(n))
  634. X#else
  635. X#include <strings.h>
  636. X#endif
  637. X
  638. char *sprintf(); /* keep lint happy */
  639. X
  640. X
  641. X/* maximum line length we'll have to deal with */
  642. X#define MAXLINE BUFSIZ
  643. X
  644. X/* maximum size of file name */
  645. X#define FILENAMESIZE 1024
  646. X
  647. X#define min(x,y) (x < y ? x : y)
  648. X#define max(x,y) (x > y ? x : y)
  649. X
  650. X#define true 1
  651. X#define false 0
  652. X
  653. X
  654. X#ifndef DEFAULT_SKELETON_FILE
  655. X#define DEFAULT_SKELETON_FILE "flex.skel"
  656. X#endif
  657. X
  658. X#ifndef FAST_SKELETON_FILE
  659. X#define FAST_SKELETON_FILE "flex.fastskel"
  660. X#endif
  661. X
  662. X/* special nxt[] action number for the "at the end of the input buffer" state */
  663. X/* note: -1 is already taken by YY_NEW_FILE */
  664. X#define END_OF_BUFFER_ACTION -3
  665. X/* action number for default action for fast scanners */
  666. X#define DEFAULT_ACTION -2
  667. X
  668. X/* special chk[] values marking the slots taking by end-of-buffer and action
  669. X * numbers
  670. X */
  671. X#define EOB_POSITION -1
  672. X#define ACTION_POSITION -2
  673. X
  674. X/* number of data items per line for -f output */
  675. X#define NUMDATAITEMS 10
  676. X
  677. X/* number of lines of data in -f output before inserting a blank line for
  678. X * readability.
  679. X */
  680. X#define NUMDATALINES 10
  681. X
  682. X/* transition_struct_out() definitions */
  683. X#define TRANS_STRUCT_PRINT_LENGTH 15
  684. X
  685. X/* returns true if an nfa state has an epsilon out-transition slot
  686. X * that can be used.  This definition is currently not used.
  687. X */
  688. X#define FREE_EPSILON(state) \
  689. X    (transchar[state] == SYM_EPSILON && \
  690. X     trans2[state] == NO_TRANSITION && \
  691. X     finalst[state] != state)
  692. X
  693. X/* returns true if an nfa state has an epsilon out-transition character
  694. X * and both slots are free
  695. X */
  696. X#define SUPER_FREE_EPSILON(state) \
  697. X    (transchar[state] == SYM_EPSILON && \
  698. X     trans1[state] == NO_TRANSITION) \
  699. X
  700. X/* maximum number of NFA states that can comprise a DFA state.  It's real
  701. X * big because if there's a lot of rules, the initial state will have a
  702. X * huge epsilon closure.
  703. X */
  704. X#define INITIAL_MAX_DFA_SIZE 750
  705. X#define MAX_DFA_SIZE_INCREMENT 750
  706. X
  707. X/* array names to be used in generated machine.  They're short because
  708. X * we write out one data statement (which names the array) for each element
  709. X * in the array.
  710. X */
  711. X
  712. X#define ALIST 'l'    /* points to list of rules accepted for a state */
  713. X#define ACCEPT 'a'    /* list of rules accepted for a state */
  714. X#define ECARRAY 'e'    /* maps input characters to equivalence classes */
  715. X#define MATCHARRAY 'm'    /* maps equivalence classes to meta-equivalence classes */
  716. X#define BASEARRAY 'b'    /* "base" array */
  717. X#define DEFARRAY 'd'    /* "default" array */
  718. X#define NEXTARRAY 'n'    /* "next" array */
  719. X#define CHECKARRAY 'c'    /* "check" array */
  720. X
  721. X/* NIL must be 0.  If not, its special meaning when making equivalence classes
  722. X * (it marks the representative of a given e.c.) will be unidentifiable
  723. X */
  724. X#define NIL 0
  725. X
  726. X#define JAM -1    /* to mark a missing DFA transition */
  727. X#define NO_TRANSITION NIL
  728. X#define UNIQUE -1    /* marks a symbol as an e.c. representative */
  729. X#define INFINITY -1    /* for x{5,} constructions */
  730. X
  731. X/* size of input alphabet - should be size of ASCII set */
  732. X#define CSIZE 127
  733. X
  734. X#define INITIAL_MAXCCLS 100    /* max number of unique character classes */
  735. X#define MAXCCLS_INCREMENT 100
  736. X
  737. X/* size of table holding members of character classes */
  738. X#define INITIAL_MAX_CCL_TBL_SIZE 500
  739. X#define MAX_CCL_TBL_SIZE_INCREMENT 250
  740. X
  741. X#define INITIAL_MNS 2000    /* default maximum number of nfa states */
  742. X#define MNS_INCREMENT 1000    /* amount to bump above by if it's not enough */
  743. X
  744. X#define INITIAL_MAX_DFAS 1000    /* default maximum number of dfa states */
  745. X#define MAX_DFAS_INCREMENT 1000
  746. X
  747. X#define JAMSTATE -32766    /* marks a reference to the state that always jams */
  748. X
  749. X/* enough so that if it's subtracted from an NFA state number, the result
  750. X * is guaranteed to be negative
  751. X */
  752. X#define MARKER_DIFFERENCE 32000
  753. X#define MAXIMUM_MNS 31999
  754. X
  755. X/* maximum number of nxt/chk pairs for non-templates */
  756. X#define INITIAL_MAX_XPAIRS 2000
  757. X#define MAX_XPAIRS_INCREMENT 2000
  758. X
  759. X/* maximum number of nxt/chk pairs needed for templates */
  760. X#define INITIAL_MAX_TEMPLATE_XPAIRS 2500
  761. X#define MAX_TEMPLATE_XPAIRS_INCREMENT 2500
  762. X
  763. X#define SYM_EPSILON 0    /* to mark transitions on the symbol epsilon */
  764. X
  765. X#define INITIAL_MAX_SCS 40    /* maximum number of start conditions */
  766. X#define MAX_SCS_INCREMENT 40    /* amount to bump by if it's not enough */
  767. X
  768. X#define ONE_STACK_SIZE 500    /* stack of states with only one out-transition */
  769. X#define SAME_TRANS -1    /* transition is the same as "default" entry for state */
  770. X
  771. X/* the following percentages are used to tune table compression:
  772. X
  773. X * the percentage the number of out-transitions a state must be of the
  774. X * number of equivalence classes in order to be considered for table
  775. X * compaction by using protos
  776. X */
  777. X#define PROTO_SIZE_PERCENTAGE 15
  778. X
  779. X/* the percentage the number of homogeneous out-transitions of a state
  780. X * must be of the number of total out-transitions of the state in order
  781. X * that the state's transition table is first compared with a potential 
  782. X * template of the most common out-transition instead of with the first
  783. X * proto in the proto queue
  784. X */
  785. X#define CHECK_COM_PERCENTAGE 50
  786. X
  787. X/* the percentage the number of differences between a state's transition
  788. X * table and the proto it was first compared with must be of the total
  789. X * number of out-transitions of the state in order to keep the first
  790. X * proto as a good match and not search any further
  791. X */
  792. X#define FIRST_MATCH_DIFF_PERCENTAGE 10
  793. X
  794. X/* the percentage the number of differences between a state's transition
  795. X * table and the most similar proto must be of the state's total number
  796. X * of out-transitions to use the proto as an acceptable close match
  797. X */
  798. X#define ACCEPTABLE_DIFF_PERCENTAGE 50
  799. X
  800. X/* the percentage the number of homogeneous out-transitions of a state
  801. X * must be of the number of total out-transitions of the state in order
  802. X * to consider making a template from the state
  803. X */
  804. X#define TEMPLATE_SAME_PERCENTAGE 60
  805. X
  806. X/* the percentage the number of differences between a state's transition
  807. X * table and the most similar proto must be of the state's total number
  808. X * of out-transitions to create a new proto from the state
  809. X */
  810. X#define NEW_PROTO_DIFF_PERCENTAGE 20
  811. X
  812. X/* the percentage the total number of out-transitions of a state must be
  813. X * of the number of equivalence classes in order to consider trying to
  814. X * fit the transition table into "holes" inside the nxt/chk table.
  815. X */
  816. X#define INTERIOR_FIT_PERCENTAGE 15
  817. X
  818. X/* size of region set aside to cache the complete transition table of
  819. X * protos on the proto queue to enable quick comparisons
  820. X */
  821. X#define PROT_SAVE_SIZE 2000
  822. X
  823. X#define MSP 50    /* maximum number of saved protos (protos on the proto queue) */
  824. X
  825. X/* maximum number of out-transitions a state can have that we'll rummage
  826. X * around through the interior of the internal fast table looking for a
  827. X * spot for it
  828. X */
  829. X#define MAX_XTIONS_FOR_FULL_INTERIOR_FIT 4
  830. X
  831. X/* number that, if used to subscript an array, has a good chance of producing
  832. X * an error; should be small enough to fit into a short
  833. X */
  834. X#define BAD_SUBSCRIPT -32767
  835. X
  836. X/* absolute value of largest number that can be stored in a short, with a
  837. X * bit of slop thrown in for general paranoia.
  838. X */
  839. X#define MAX_SHORT 32766
  840. X
  841. X
  842. X/* Declarations for global variables. */
  843. X
  844. X/* variables for symbol tables:
  845. X * sctbl - start-condition symbol table
  846. X * ndtbl - name-definition symbol table
  847. X * ccltab - character class text symbol table
  848. X */
  849. X
  850. struct hash_entry
  851. X    {
  852. X    struct hash_entry *prev, *next;
  853. X    char *name;
  854. X    char *str_val;
  855. X    int int_val;
  856. X    } ;
  857. X
  858. typedef struct hash_entry *hash_table[];
  859. X
  860. X#define NAME_TABLE_HASH_SIZE 101
  861. X#define START_COND_HASH_SIZE 101
  862. X#define CCL_HASH_SIZE 101
  863. X
  864. extern struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE]; 
  865. extern struct hash_entry *sctbl[START_COND_HASH_SIZE];
  866. extern struct hash_entry *ccltab[CCL_HASH_SIZE];
  867. X
  868. X
  869. X/* variables for flags:
  870. X * printstats - if true (-v), dump statistics
  871. X * syntaxerror - true if a syntax error has been found
  872. X * eofseen - true if we've seen an eof in the input file
  873. X * ddebug - if true (-d), make a "debug" scanner
  874. X * trace - if true (-T), trace processing
  875. X * spprdflt - if true (-s), suppress the default rule
  876. X * interactive - if true (-I), generate an interactive scanner
  877. X * caseins - if true (-i), generate a case-insensitive scanner
  878. X * useecs - if true (-ce flag), use equivalence classes
  879. X * fulltbl - if true (-cf flag), don't compress the DFA state table
  880. X * usemecs - if true (-cm flag), use meta-equivalence classes
  881. X * reject - if true (-r flag), generate tables for REJECT macro
  882. X * fullspd - if true (-F flag), use Jacobson method of table representation
  883. X * gen_line_dirs - if true (i.e., no -L flag), generate #line directives
  884. X */
  885. X
  886. extern int printstats, syntaxerror, eofseen, ddebug, trace, spprdflt;
  887. extern int interactive, caseins, useecs, fulltbl, usemecs, reject;
  888. extern int fullspd, gen_line_dirs;
  889. X
  890. X
  891. X/* variables used in the flex input routines:
  892. X * datapos - characters on current output line
  893. X * dataline - number of contiguous lines of data in current data
  894. X *    statement.  Used to generate readable -f output
  895. X * skelfile - fd of the skeleton file
  896. X * yyin - input file
  897. X * temp_action_file - temporary file to hold actions
  898. X * action_file_name - name of the temporary file
  899. X * infilename - name of input file
  900. X * linenum - current input line number
  901. X */
  902. X
  903. extern int datapos, dataline, linenum;
  904. extern FILE *skelfile, *yyin, *temp_action_file;
  905. extern char *infilename;
  906. extern char *action_file_name;
  907. X
  908. X
  909. X/* variables for stack of states having only one out-transition:
  910. X * onestate - state number
  911. X * onesym - transition symbol
  912. X * onenext - target state
  913. X * onedef - default base entry
  914. X * onesp - stack pointer
  915. X */
  916. X
  917. extern int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE];
  918. extern int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp;
  919. X
  920. X
  921. X/* variables for nfa machine data:
  922. X * current_mns - current maximum on number of NFA states
  923. X * accnum - number of the last accepting state
  924. X * firstst - physically the first state of a fragment
  925. X * lastst - last physical state of fragment
  926. X * finalst - last logical state of fragment
  927. X * transchar - transition character
  928. X * trans1 - transition state
  929. X * trans2 - 2nd transition state for epsilons
  930. X * accptnum - accepting number
  931. X * lastnfa - last nfa state number created
  932. X */
  933. X
  934. extern int current_mns;
  935. extern int accnum, *firstst, *lastst, *finalst, *transchar;
  936. extern int *trans1, *trans2, *accptnum, lastnfa;
  937. X
  938. X
  939. X/* variables for protos:
  940. X * numtemps - number of templates created
  941. X * numprots - number of protos created
  942. X * protprev - backlink to a more-recently used proto
  943. X * protnext - forward link to a less-recently used proto
  944. X * prottbl - base/def table entry for proto
  945. X * protcomst - common state of proto
  946. X * firstprot - number of the most recently used proto
  947. X * lastprot - number of the least recently used proto
  948. X * protsave contains the entire state array for protos
  949. X */
  950. X
  951. extern int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP];
  952. extern int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE];
  953. X
  954. X
  955. X/* variables for managing equivalence classes:
  956. X * numecs - number of equivalence classes
  957. X * nextecm - forward link of Equivalence Class members
  958. X * ecgroup - class number or backward link of EC members
  959. X * nummecs - number of meta-equivalence classes (used to compress
  960. X *   templates)
  961. X * tecfwd - forward link of meta-equivalence classes members
  962. X * tecbck - backward link of MEC's
  963. X */
  964. X
  965. extern int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs;
  966. extern int tecfwd[CSIZE + 1], tecbck[CSIZE + 1];
  967. X
  968. X
  969. X/* variables for start conditions:
  970. X * lastsc - last start condition created
  971. X * current_max_scs - current limit on number of start conditions
  972. X * scset - set of rules active in start condition
  973. X * scbol - set of rules active only at the beginning of line in a s.c.
  974. X * scxclu - true if start condition is exclusive
  975. X * actvsc - stack of active start conditions for the current rule
  976. X */
  977. X
  978. extern int lastsc, current_max_scs, *scset, *scbol, *scxclu, *actvsc;
  979. X
  980. X
  981. X/* variables for dfa machine data:
  982. X * current_max_dfa_size - current maximum number of NFA states in DFA
  983. X * current_max_xpairs - current maximum number of non-template xtion pairs
  984. X * current_max_template_xpairs - current maximum number of template pairs
  985. X * current_max_dfas - current maximum number DFA states
  986. X * lastdfa - last dfa state number created
  987. X * nxt - state to enter upon reading character
  988. X * chk - check value to see if "nxt" applies
  989. X * tnxt - internal nxt table for templates
  990. X * base - offset into "nxt" for given state
  991. X * def - where to go if "chk" disallows "nxt" entry
  992. X * tblend - last "nxt/chk" table entry being used
  993. X * firstfree - first empty entry in "nxt/chk" table
  994. X * dss - nfa state set for each dfa
  995. X * dfasiz - size of nfa state set for each dfa
  996. X * dfaacc - accepting set for each dfa state (or accepting number, if
  997. X *    -r is not given)
  998. X * accsiz - size of accepting set for each dfa state
  999. X * dhash - dfa state hash value
  1000. X * todo - queue of DFAs still to be processed
  1001. X * todo_head - head of todo queue
  1002. X * todo_next - next available entry on todo queue
  1003. X * numas - number of DFA accepting states created; note that this
  1004. X *    is not necessarily the same value as accnum, which is the analogous
  1005. X *    value for the NFA
  1006. X * numsnpairs - number of state/nextstate transition pairs
  1007. X * jambase - position in base/def where the default jam table starts
  1008. X * jamstate - state number corresponding to "jam" state
  1009. X * end_of_buffer_state - end-of-buffer dfa state number
  1010. X */
  1011. X
  1012. extern int current_max_dfa_size, current_max_xpairs;
  1013. extern int current_max_template_xpairs, current_max_dfas;
  1014. extern int lastdfa, lasttemp, *nxt, *chk, *tnxt;
  1015. extern int *base, *def, tblend, firstfree, **dss, *dfasiz;
  1016. extern union dfaacc_union
  1017. X    {
  1018. X    int *dfaacc_set;
  1019. X    int dfaacc_state;
  1020. X    } *dfaacc;
  1021. extern int *accsiz, *dhash, *todo, todo_head, todo_next, numas;
  1022. extern int numsnpairs, jambase, jamstate;
  1023. extern int end_of_buffer_state;
  1024. X
  1025. X/* variables for ccl information:
  1026. X * lastccl - ccl index of the last created ccl
  1027. X * current_maxccls - current limit on the maximum number of unique ccl's
  1028. X * cclmap - maps a ccl index to its set pointer
  1029. X * ccllen - gives the length of a ccl
  1030. X * cclng - true for a given ccl if the ccl is negated
  1031. X * cclreuse - counts how many times a ccl is re-used
  1032. X * current_max_ccl_tbl_size - current limit on number of characters needed
  1033. X *    to represent the unique ccl's
  1034. X * ccltbl - holds the characters in each ccl - indexed by cclmap
  1035. X */
  1036. X
  1037. extern int lastccl, current_maxccls, *cclmap, *ccllen, *cclng, cclreuse;
  1038. extern int current_max_ccl_tbl_size;
  1039. extern char *ccltbl;
  1040. X
  1041. X
  1042. X/* variables for miscellaneous information:
  1043. X * starttime - real-time when we started
  1044. X * endtime - real-time when we ended
  1045. X * nmstr - last NAME scanned by the scanner
  1046. X * sectnum - section number currently being parsed
  1047. X * nummt - number of empty nxt/chk table entries
  1048. X * hshcol - number of hash collisions detected by snstods
  1049. X * dfaeql - number of times a newly created dfa was equal to an old one
  1050. X * numeps - number of epsilon NFA states created
  1051. X * eps2 - number of epsilon states which have 2 out-transitions
  1052. X * num_reallocs - number of times it was necessary to realloc() a group
  1053. X *          of arrays
  1054. X * tmpuses - number of DFA states that chain to templates
  1055. X * totnst - total number of NFA states used to make DFA states
  1056. X * peakpairs - peak number of transition pairs we had to store internally
  1057. X * numuniq - number of unique transitions
  1058. X * numdup - number of duplicate transitions
  1059. X * hshsave - number of hash collisions saved by checking number of states
  1060. X */
  1061. X
  1062. extern char *starttime, *endtime, nmstr[MAXLINE];
  1063. extern int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs;
  1064. extern int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave;
  1065. X
  1066. char *allocate_array(), *reallocate_array();
  1067. X
  1068. X#define allocate_integer_array(size) \
  1069. X    (int *) allocate_array( size, sizeof( int ) )
  1070. X
  1071. X#define reallocate_integer_array(array,size) \
  1072. X    (int *) reallocate_array( (char *) array, size, sizeof( int ) )
  1073. X
  1074. X#define allocate_integer_pointer_array(size) \
  1075. X    (int **) allocate_array( size, sizeof( int * ) )
  1076. X
  1077. X#define allocate_dfaacc_union(size) \
  1078. X    (union dfaacc_union *) \
  1079. X        allocate_array( size, sizeof( union dfaacc_union ) )
  1080. X
  1081. X#define reallocate_integer_pointer_array(array,size) \
  1082. X    (int **) reallocate_array( (char *) array, size, sizeof( int * ) )
  1083. X
  1084. X#define reallocate_dfaacc_union(array, size) \
  1085. X    (union dfaacc_union *)  reallocate_array( (char *) array, size, sizeof( union dfaacc_union ) )
  1086. X
  1087. X#define allocate_character_array(size) allocate_array( size, sizeof( char ) )
  1088. X
  1089. X#define reallocate_character_array(array,size) \
  1090. X    reallocate_array( array, size, sizeof( char ) )
  1091. X
  1092. X
  1093. X/* used to communicate between scanner and parser.  The type should really
  1094. X * be YYSTYPE, but we can't easily get our hands on it.
  1095. X */
  1096. extern int yylval;
  1097. END_OF_FILE
  1098. if test 17327 -ne `wc -c <'flexdef.h'`; then
  1099.     echo shar: \"'flexdef.h'\" unpacked with wrong size!
  1100. fi
  1101. # end of 'flexdef.h'
  1102. fi
  1103. if test -f 'nfa.c' -a "${1}" != "-c" ; then 
  1104.   echo shar: Will not clobber existing file \"'nfa.c'\"
  1105. else
  1106. echo shar: Extracting \"'nfa.c'\" \(13633 characters\)
  1107. sed "s/^X//" >'nfa.c' <<'END_OF_FILE'
  1108. X/* nfa - NFA construction routines */
  1109. X
  1110. X/*
  1111. X * Copyright (c) 1987, the University of California
  1112. X * 
  1113. X * The United States Government has rights in this work pursuant to
  1114. X * contract no. DE-AC03-76SF00098 between the United States Department of
  1115. X * Energy and the University of California.
  1116. X * 
  1117. X * This program may be redistributed.  Enhancements and derivative works
  1118. X * may be created provided the new works, if made available to the general
  1119. X * public, are made available for use by anyone.
  1120. X */
  1121. X
  1122. X#include "flexdef.h"
  1123. X
  1124. X/* add_accept - add an accepting state to a machine
  1125. X *
  1126. X * synopsis
  1127. X *
  1128. X *   add_accept( mach, headcnt, trailcnt );
  1129. X *
  1130. X * the global ACCNUM is incremented and the new value becomes mach's
  1131. X * accepting number.  if headcnt or trailcnt is non-zero then the machine
  1132. X * recognizes a pattern with trailing context.  headcnt is the number of
  1133. X * characters in the matched part of the pattern, or zero if the matched
  1134. X * part has variable length.  trailcnt is the number of trailing context
  1135. X * characters in the pattern, or zero if the trailing context has variable
  1136. X * length.
  1137. X */
  1138. X
  1139. add_accept( mach, headcnt, trailcnt )
  1140. int mach, headcnt, trailcnt;
  1141. X
  1142. X    {
  1143. X    int astate;
  1144. X
  1145. X    fprintf( temp_action_file, "case %d:\n", ++accnum );
  1146. X
  1147. X    if ( headcnt > 0 || trailcnt > 0 )
  1148. X    { /* do trailing context magic to not match the trailing characters */
  1149. X    fprintf( temp_action_file,
  1150. X        "YY_DO_BEFORE_SCAN; /* undo effects of setting up yytext */\n" );
  1151. X
  1152. X    if ( headcnt > 0 )
  1153. X        {
  1154. X        int head_offset = headcnt - 1;
  1155. X
  1156. X        if ( fullspd || fulltbl )
  1157. X        /* with the fast skeleton, yy_c_buf_p points to the *next*
  1158. X         * character to scan, rather than the one that was last
  1159. X         * scanned
  1160. X         */
  1161. X        ++head_offset;
  1162. X
  1163. X        if ( head_offset > 0 )
  1164. X        fprintf( temp_action_file, "yy_c_buf_p = yy_b_buf_p + %d;\n",
  1165. X             head_offset );
  1166. X
  1167. X        else
  1168. X        fprintf( temp_action_file, "yy_c_buf_p = yy_b_buf_p;\n" );
  1169. X        }
  1170. X
  1171. X    else
  1172. X        fprintf( temp_action_file, "yy_c_buf_p -= %d;\n", trailcnt );
  1173. X    
  1174. X    fprintf( temp_action_file, "YY_DO_BEFORE_ACTION; /* set up yytext again */\n" );
  1175. X    }
  1176. X
  1177. X    line_directive_out( temp_action_file );
  1178. X
  1179. X    /* hang the accepting number off an epsilon state.  if it is associated
  1180. X     * with a state that has a non-epsilon out-transition, then the state
  1181. X     * will accept BEFORE it makes that transition, i.e., one character
  1182. X     * too soon
  1183. X     */
  1184. X
  1185. X    if ( transchar[finalst[mach]] == SYM_EPSILON )
  1186. X    accptnum[finalst[mach]] = accnum;
  1187. X
  1188. X    else
  1189. X    {
  1190. X    astate = mkstate( SYM_EPSILON );
  1191. X    accptnum[astate] = accnum;
  1192. X    mach = link_machines( mach, astate );
  1193. X    }
  1194. X    }
  1195. X
  1196. X
  1197. X/* copysingl - make a given number of copies of a singleton machine
  1198. X *
  1199. X * synopsis
  1200. X *
  1201. X *   newsng = copysingl( singl, num );
  1202. X *
  1203. X *     newsng - a new singleton composed of num copies of singl
  1204. X *     singl  - a singleton machine
  1205. X *     num    - the number of copies of singl to be present in newsng
  1206. X */
  1207. X
  1208. int copysingl( singl, num )
  1209. int singl, num;
  1210. X
  1211. X    {
  1212. X    int copy, i;
  1213. X
  1214. X    copy = mkstate( SYM_EPSILON );
  1215. X
  1216. X    for ( i = 1; i <= num; ++i )
  1217. X    copy = link_machines( copy, dupmachine( singl ) );
  1218. X
  1219. X    return ( copy );
  1220. X    }
  1221. X
  1222. X
  1223. X/* dumpnfa - debugging routine to write out an nfa
  1224. X *
  1225. X * synopsis
  1226. X *    int state1;
  1227. X *    dumpnfa( state1 );
  1228. X */
  1229. X
  1230. dumpnfa( state1 )
  1231. int state1;
  1232. X
  1233. X    {
  1234. X    int sym, tsp1, tsp2, anum, ns;
  1235. X
  1236. X    fprintf( stderr, "\n\n********** beginning dump of nfa with start state %d\n",
  1237. X         state1 );
  1238. X
  1239. X    /* we probably should loop starting at firstst[state1] and going to
  1240. X     * lastst[state1], but they're not maintained properly when we "or"
  1241. X     * all of the rules together.  So we use our knowledge that the machine
  1242. X     * starts at state 1 and ends at lastnfa.
  1243. X     */
  1244. X
  1245. X    /* for ( ns = firstst[state1]; ns <= lastst[state1]; ++ns ) */
  1246. X    for ( ns = 1; ns <= lastnfa; ++ns )
  1247. X    {
  1248. X    fprintf( stderr, "state # %4d\t", ns );
  1249. X
  1250. X    sym = transchar[ns];
  1251. X    tsp1 = trans1[ns];
  1252. X    tsp2 = trans2[ns];
  1253. X    anum = accptnum[ns];
  1254. X
  1255. X    fprintf( stderr, "%3d:  %4d, %4d", sym, tsp1, tsp2 );
  1256. X
  1257. X    if ( anum != NIL )
  1258. X        fprintf( stderr, "  [%d]", anum );
  1259. X
  1260. X    fprintf( stderr, "\n" );
  1261. X    }
  1262. X
  1263. X    fprintf( stderr, "********** end of dump\n" );
  1264. X    }
  1265. X
  1266. X
  1267. X/* dupmachine - make a duplicate of a given machine
  1268. X *
  1269. X * synopsis
  1270. X *
  1271. X *   copy = dupmachine( mach );
  1272. X *
  1273. X *     copy - holds duplicate of mach
  1274. X *     mach - machine to be duplicated
  1275. X *
  1276. X * note that the copy of mach is NOT an exact duplicate; rather, all the
  1277. X * transition states values are adjusted so that the copy is self-contained,
  1278. X * as the original should have been.
  1279. X *
  1280. X * also note that the original MUST be contiguous, with its low and high
  1281. X * states accessible by the arrays firstst and lastst
  1282. X */
  1283. X
  1284. int dupmachine( mach )
  1285. int mach;
  1286. X
  1287. X    {
  1288. X    int i, state, init, last = lastst[mach], state_offset;
  1289. X
  1290. X    for ( i = firstst[mach]; i <= last; ++i )
  1291. X    {
  1292. X    state = mkstate( transchar[i] );
  1293. X
  1294. X    if ( trans1[i] != NO_TRANSITION )
  1295. X        {
  1296. X        mkxtion( finalst[state], trans1[i] + state - i );
  1297. X
  1298. X        if ( transchar[i] == SYM_EPSILON && trans2[i] != NO_TRANSITION )
  1299. X        mkxtion( finalst[state], trans2[i] + state - i );
  1300. X        }
  1301. X
  1302. X    accptnum[state] = accptnum[i];
  1303. X    }
  1304. X
  1305. X    state_offset = state - i + 1;
  1306. X
  1307. X    init = mach + state_offset;
  1308. X    firstst[init] = firstst[mach] + state_offset;
  1309. X    finalst[init] = finalst[mach] + state_offset;
  1310. X    lastst[init] = lastst[mach] + state_offset;
  1311. X
  1312. X    return ( init );
  1313. X    }
  1314. X
  1315. X
  1316. X/* link_machines - connect two machines together
  1317. X *
  1318. X * synopsis
  1319. X *
  1320. X *   new = link_machines( first, last );
  1321. X *
  1322. X *     new    - a machine constructed by connecting first to last
  1323. X *     first  - the machine whose successor is to be last
  1324. X *     last   - the machine whose predecessor is to be first
  1325. X *
  1326. X * note: this routine concatenates the machine first with the machine
  1327. X *  last to produce a machine new which will pattern-match first first
  1328. X *  and then last, and will fail if either of the sub-patterns fails.
  1329. X *  FIRST is set to new by the operation.  last is unmolested.
  1330. X */
  1331. X
  1332. int link_machines( first, last )
  1333. int first, last;
  1334. X
  1335. X    {
  1336. X    if ( first == NIL )
  1337. X    return ( last );
  1338. X
  1339. X    else if ( last == NIL )
  1340. X    return ( first );
  1341. X
  1342. X    else
  1343. X    {
  1344. X    mkxtion( finalst[first], last );
  1345. X    finalst[first] = finalst[last];
  1346. X    lastst[first] = max( lastst[first], lastst[last] );
  1347. X    firstst[first] = min( firstst[first], firstst[last] );
  1348. X
  1349. X    return ( first );
  1350. X    }
  1351. X    }
  1352. X
  1353. X
  1354. X/* mkbranch - make a machine that branches to two machines
  1355. X *
  1356. X * synopsis
  1357. X *
  1358. X *   branch = mkbranch( first, second );
  1359. X *
  1360. X *     branch - a machine which matches either first's pattern or second's
  1361. X *     first, second - machines whose patterns are to be or'ed (the | operator)
  1362. X *
  1363. X * note that first and second are NEITHER destroyed by the operation.  Also,
  1364. X * the resulting machine CANNOT be used with any other "mk" operation except
  1365. X * more mkbranch's.  Compare with mkor()
  1366. X */
  1367. X
  1368. int mkbranch( first, second )
  1369. int first, second;
  1370. X
  1371. X    {
  1372. X    int eps;
  1373. X
  1374. X    if ( first == NO_TRANSITION )
  1375. X    return ( second );
  1376. X
  1377. X    else if ( second == NO_TRANSITION )
  1378. X    return ( first );
  1379. X
  1380. X    eps = mkstate( SYM_EPSILON );
  1381. X
  1382. X    mkxtion( eps, first );
  1383. X    mkxtion( eps, second );
  1384. X
  1385. X    return ( eps );
  1386. X    }
  1387. X
  1388. X
  1389. X/* mkclos - convert a machine into a closure
  1390. X *
  1391. X * synopsis
  1392. X *   new = mkclos( state );
  1393. X *
  1394. X *     new - a new state which matches the closure of "state"
  1395. X */
  1396. X
  1397. int mkclos( state )
  1398. int state;
  1399. X
  1400. X    {
  1401. X    return ( mkopt( mkposcl( state ) ) );
  1402. X    }
  1403. X
  1404. X
  1405. X/* mkopt - make a machine optional
  1406. X *
  1407. X * synopsis
  1408. X *
  1409. X *   new = mkopt( mach );
  1410. X *
  1411. X *     new  - a machine which optionally matches whatever mach matched
  1412. X *     mach - the machine to make optional
  1413. X *
  1414. X * notes:
  1415. X *     1. mach must be the last machine created
  1416. X *     2. mach is destroyed by the call
  1417. X */
  1418. X
  1419. int mkopt( mach )
  1420. int mach;
  1421. X
  1422. X    {
  1423. X    int eps;
  1424. X
  1425. X    if ( ! SUPER_FREE_EPSILON(finalst[mach]) )
  1426. X    {
  1427. X    eps = mkstate( SYM_EPSILON );
  1428. X    mach = link_machines( mach, eps );
  1429. X    }
  1430. X
  1431. X    /* can't skimp on the following if FREE_EPSILON(mach) is true because
  1432. X     * some state interior to "mach" might point back to the beginning
  1433. X     * for a closure
  1434. X     */
  1435. X    eps = mkstate( SYM_EPSILON );
  1436. X    mach = link_machines( eps, mach );
  1437. X
  1438. X    mkxtion( mach, finalst[mach] );
  1439. X
  1440. X    return ( mach );
  1441. X    }
  1442. X
  1443. X
  1444. X/* mkor - make a machine that matches either one of two machines
  1445. X *
  1446. X * synopsis
  1447. X *
  1448. X *   new = mkor( first, second );
  1449. X *
  1450. X *     new - a machine which matches either first's pattern or second's
  1451. X *     first, second - machines whose patterns are to be or'ed (the | operator)
  1452. X *
  1453. X * note that first and second are both destroyed by the operation
  1454. X * the code is rather convoluted because an attempt is made to minimize
  1455. X * the number of epsilon states needed
  1456. X */
  1457. X
  1458. int mkor( first, second )
  1459. int first, second;
  1460. X
  1461. X    {
  1462. X    int eps, orend;
  1463. X
  1464. X    if ( first == NIL )
  1465. X    return ( second );
  1466. X
  1467. X    else if ( second == NIL )
  1468. X    return ( first );
  1469. X
  1470. X    else
  1471. X    {
  1472. X    /* see comment in mkopt() about why we can't use the first state
  1473. X     * of "first" or "second" if they satisfy "FREE_EPSILON"
  1474. X     */
  1475. X    eps = mkstate( SYM_EPSILON );
  1476. X
  1477. X    first = link_machines( eps, first );
  1478. X
  1479. X    mkxtion( first, second );
  1480. X
  1481. X    if ( SUPER_FREE_EPSILON(finalst[first]) &&
  1482. X         accptnum[finalst[first]] == NIL )
  1483. X        {
  1484. X        orend = finalst[first];
  1485. X        mkxtion( finalst[second], orend );
  1486. X        }
  1487. X
  1488. X    else if ( SUPER_FREE_EPSILON(finalst[second]) &&
  1489. X          accptnum[finalst[second]] == NIL )
  1490. X        {
  1491. X        orend = finalst[second];
  1492. X        mkxtion( finalst[first], orend );
  1493. X        }
  1494. X
  1495. X    else
  1496. X        {
  1497. X        eps = mkstate( SYM_EPSILON );
  1498. X
  1499. X        first = link_machines( first, eps );
  1500. X        orend = finalst[first];
  1501. X
  1502. X        mkxtion( finalst[second], orend );
  1503. X        }
  1504. X    }
  1505. X
  1506. X    finalst[first] = orend;
  1507. X    return ( first );
  1508. X    }
  1509. X
  1510. X
  1511. X/* mkposcl - convert a machine into a positive closure
  1512. X *
  1513. X * synopsis
  1514. X *   new = mkposcl( state );
  1515. X *
  1516. X *    new - a machine matching the positive closure of "state"
  1517. X */
  1518. X
  1519. int mkposcl( state )
  1520. int state;
  1521. X
  1522. X    {
  1523. X    int eps;
  1524. X
  1525. X    if ( SUPER_FREE_EPSILON(finalst[state]) )
  1526. X    {
  1527. X    mkxtion( finalst[state], state );
  1528. X    return ( state );
  1529. X    }
  1530. X
  1531. X    else
  1532. X    {
  1533. X    eps = mkstate( SYM_EPSILON );
  1534. X    mkxtion( eps, state );
  1535. X    return ( link_machines( state, eps ) );
  1536. X    }
  1537. X    }
  1538. X
  1539. X
  1540. X/* mkrep - make a replicated machine
  1541. X *
  1542. X * synopsis
  1543. X *   new = mkrep( mach, lb, ub );
  1544. X *
  1545. X *    new - a machine that matches whatever "mach" matched from "lb"
  1546. X *          number of times to "ub" number of times
  1547. X *
  1548. X * note
  1549. X *   if "ub" is INFINITY then "new" matches "lb" or more occurrences of "mach"
  1550. X */
  1551. X
  1552. int mkrep( mach, lb, ub )
  1553. int mach, lb, ub;
  1554. X
  1555. X    {
  1556. X    int base, tail, copy, i;
  1557. X
  1558. X    base = copysingl( mach, lb - 1 );
  1559. X
  1560. X    if ( ub == INFINITY )
  1561. X    {
  1562. X    copy = dupmachine( mach );
  1563. X    mach = link_machines( mach, link_machines( base, mkclos( copy ) ) );
  1564. X    }
  1565. X
  1566. X    else
  1567. X    {
  1568. X    tail = mkstate( SYM_EPSILON );
  1569. X
  1570. X    for ( i = lb; i < ub; ++i )
  1571. X        {
  1572. X        copy = dupmachine( mach );
  1573. X        tail = mkopt( link_machines( copy, tail ) );
  1574. X        }
  1575. X
  1576. X    mach = link_machines( mach, link_machines( base, tail ) );
  1577. X    }
  1578. X
  1579. X    return ( mach );
  1580. X    }
  1581. X
  1582. X
  1583. X/* mkstate - create a state with a transition on a given symbol
  1584. X *
  1585. X * synopsis
  1586. X *
  1587. X *   state = mkstate( sym );
  1588. X *
  1589. X *     state - a new state matching sym
  1590. X *     sym   - the symbol the new state is to have an out-transition on
  1591. X *
  1592. X * note that this routine makes new states in ascending order through the
  1593. X * state array (and increments LASTNFA accordingly).  The routine DUPMACHINE
  1594. X * relies on machines being made in ascending order and that they are
  1595. X * CONTIGUOUS.  Change it and you will have to rewrite DUPMACHINE (kludge
  1596. X * that it admittedly is)
  1597. X */
  1598. X
  1599. int mkstate( sym )
  1600. int sym;
  1601. X
  1602. X    {
  1603. X    if ( ++lastnfa >= current_mns )
  1604. X    {
  1605. X    if ( (current_mns += MNS_INCREMENT) >= MAXIMUM_MNS )
  1606. X        lerrif( "input rules are too complicated (>= %d NFA states)",
  1607. X            current_mns );
  1608. X    
  1609. X    ++num_reallocs;
  1610. X
  1611. X    transchar = reallocate_integer_array( transchar, current_mns );
  1612. X    trans1 = reallocate_integer_array( trans1, current_mns );
  1613. X    trans2 = reallocate_integer_array( trans2, current_mns );
  1614. X    accptnum = reallocate_integer_array( accptnum, current_mns );
  1615. X    firstst = reallocate_integer_array( firstst, current_mns );
  1616. X    finalst = reallocate_integer_array( finalst, current_mns );
  1617. X    lastst = reallocate_integer_array( lastst, current_mns );
  1618. X    }
  1619. X
  1620. X    transchar[lastnfa] = sym;
  1621. X    trans1[lastnfa] = NO_TRANSITION;
  1622. X    trans2[lastnfa] = NO_TRANSITION;
  1623. X    accptnum[lastnfa] = NIL;
  1624. X    firstst[lastnfa] = lastnfa;
  1625. X    finalst[lastnfa] = lastnfa;
  1626. X    lastst[lastnfa] = lastnfa;
  1627. X
  1628. X    /* fix up equivalence classes base on this transition.  Note that any
  1629. X     * character which has its own transition gets its own equivalence class.
  1630. X     * Thus only characters which are only in character classes have a chance
  1631. X     * at being in the same equivalence class.  E.g. "a|b" puts 'a' and 'b'
  1632. X     * into two different equivalence classes.  "[ab]" puts them in the same
  1633. X     * equivalence class (barring other differences elsewhere in the input).
  1634. X     */
  1635. X
  1636. X    if ( sym < 0 )
  1637. X    {
  1638. X    /* we don't have to update the equivalence classes since that was
  1639. X     * already done when the ccl was created for the first time
  1640. X     */
  1641. X    }
  1642. X
  1643. X    else if ( sym == SYM_EPSILON )
  1644. X    ++numeps;
  1645. X
  1646. X    else
  1647. X    {
  1648. X    if ( useecs )
  1649. X        mkechar( sym, nextecm, ecgroup );
  1650. X    }
  1651. X
  1652. X    return ( lastnfa );
  1653. X    }
  1654. X
  1655. X
  1656. X/* mkxtion - make a transition from one state to another
  1657. X *
  1658. X * synopsis
  1659. X *
  1660. X *   mkxtion( statefrom, stateto );
  1661. X *
  1662. X *     statefrom - the state from which the transition is to be made
  1663. X *     stateto   - the state to which the transition is to be made
  1664. X */
  1665. X
  1666. mkxtion( statefrom, stateto )
  1667. int statefrom, stateto;
  1668. X
  1669. X    {
  1670. X    if ( trans1[statefrom] == NO_TRANSITION )
  1671. X    trans1[statefrom] = stateto;
  1672. X
  1673. X    else if ( (transchar[statefrom] != SYM_EPSILON) ||
  1674. X          (trans2[statefrom] != NO_TRANSITION) )
  1675. X    flexfatal( "found too many transitions in mkxtion()" );
  1676. X
  1677. X    else
  1678. X    { /* second out-transition for an epsilon state */
  1679. X    ++eps2;
  1680. X    trans2[statefrom] = stateto;
  1681. X    }
  1682. X    }
  1683. END_OF_FILE
  1684. if test 13633 -ne `wc -c <'nfa.c'`; then
  1685.     echo shar: \"'nfa.c'\" unpacked with wrong size!
  1686. fi
  1687. # end of 'nfa.c'
  1688. fi
  1689. echo shar: End of archive 3 \(of 5\).
  1690. cp /dev/null ark3isdone
  1691. MISSING=""
  1692. for I in 1 2 3 4 5 ; do
  1693.     if test ! -f ark${I}isdone ; then
  1694.     MISSING="${MISSING} ${I}"
  1695.     fi
  1696. done
  1697. if test "${MISSING}" = "" ; then
  1698.     echo You have unpacked all 5 archives.
  1699.     rm -f ark[1-9]isdone
  1700. else
  1701.     echo You still need to unpack the following archives:
  1702.     echo "        " ${MISSING}
  1703. fi
  1704. ##  End of shell archive.
  1705. exit 0
  1706.